#lang scheme
(#%require r5rs/init)


(define a #f)                              
(define test
  (lambda ()
    (let ((n 0))
      (call/cc (lambda (k)                 ;扑捉contionuation
                 (set! a k)))              ;将continuation赋给变量a
      (set! n (+ n 1))
      n)))
(test)

(define reciprocals
  (lambda (ls)
    (call/cc
     (lambda (k)                          ;扑捉continuation
       (map (lambda (x)
              (if (= x 0)
                  (k "zero found")       ;显示调用k，将(call/cc...)替换为传给k的值（"zero found")
                         (/1 x)))
            ls)))))
(reciprocals '(1 2 3 01 4 5))



#lang racket
;(define map1
;  (lambda (p ls)
;    (if (null? (cdr ls))
;        (car ls)
;        (p (car ls)
;              (map1 p (cdr ls))))))

;(define map2
;  (lambda (p ls k)
;    (if (null? ls)
;        (k '())
;        (map2 p
;              (cdr ls)
;              (lambda (v)
;                (p (car ls)
;                   (lambda (n)
;                     (k (cons n v)))))))))

;(define reciprocals
;  (lambda (ls k)
;    (let ([break k])
;      (map2
;       (lambda (x k)
;         (if (= x 0)
;             (break "error")
;             (k (/ 1 x))))
;       ls
;       k))))

(define reciprocals
  (lambda (ls k)
    (let ([break k])
      (let map1 ([p (lambda (x k)
                      (if (= x 0)
                          (break "error")
                          (k (/ 1 x))))]
                 [ls ls]
                 [k k])
        (if (null? ls)
            (k '())
            (map1
             p
             (cdr ls)
             (lambda (v)
               (p (car ls)
                  (lambda (n)
                    (k (cons n v)))))))))))

(reciprocals '(1 1/3 5 0 1/4) (lambda (x) x))


(define reciprocals
  (lambda (ls k)
    (let ([break k])
      (let f ([ls ls] [k k])
        (cond
          [(null? ls) (k '())]
          [(= (car ls) 0) (break "zero!")]
          [else (f (cdr ls)
                   (lambda (x)
                     (k (cons
                         (/ 1 (car ls))
                         x))))])))))

(define product
  (lambda (ls)
    (call/cc
     (lambda (break)
       (let f ([ls ls])
         (cond 
           [(null? ls) 1]
           [(= (car ls) 0) (break "zero")]
           [else (* (car ls) (f (cdr ls)))]))))))
(product '(1 2 3 4 5))

;;使用尾部递归模拟cps
(define map1
  (lambda (p list devide result)
    (cond ((null? list) result)
          ((= (car list) 4) 'hellworld)
          (else (map1 p 
                      (cdr list) 
                      devide 
                      (cons (p (car list) devide) result))))))
(map1 / '(1 2 3 7 41 5 6) 3 '())
